package cn.yeziji.forum.dao.impl;

import cn.yeziji.forum.dao.base.ForumUserQaBaseDao;
import cn.yeziji.forum.dao.intf.ForumUserQaDao;
import cn.yeziji.forum.dao.iquery.UserQaQuery;
import cn.yeziji.forum.dao.iupdater.AnswerUpdater;
import cn.yeziji.forum.dao.iupdater.QuestionUpdater;
import cn.yeziji.forum.entity.ForumUserQaEntity;
import cn.yeziji.forum.exception.ForumException;
import cn.yeziji.forum.exception.UserQaException;
import cn.yeziji.forum.mapper.ForumAnswerMapper;
import cn.yeziji.forum.mapper.ForumQuestionMapper;
import cn.yeziji.forum.common.enums.status.UserQaStatus;
import cn.yeziji.forum.utils.JwtOperaUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;

/**
 * 用户操作问业务逻辑层
 *
 * @author gzkemays
 * @since 2022/11/15 2:03 PM
 */
@Repository
public class ForumUserQaDaoImpl extends ForumUserQaBaseDao implements ForumUserQaDao {
  @Resource ForumQuestionMapper questionMapper;
  @Resource ForumAnswerMapper answerMapper;
  @Resource HttpServletRequest request;

  @Override
  @Transactional(rollbackFor = {ForumException.class})
  public boolean userCollectionQuestion(Integer questionId) {
    Integer userId = JwtOperaUtils.getUserIdByRequest(request);
    return userOperaQuestionOrAnswer(userId, questionId, QUESTION_MODE);
  }

  @Override
  @Transactional(rollbackFor = {ForumException.class})
  public boolean userKudosAnswer(Integer answerId) {
    Integer userId = JwtOperaUtils.getUserIdByRequest(request);
    return userOperaQuestionOrAnswer(userId, answerId, ANSWER_MODE);
  }

  private boolean userOperaQuestionOrAnswer(Integer userId, Integer id, Integer mode) {
    Optional<ForumUserQaEntity> entityOptional =
        mode.equals(QUESTION_MODE)
            ? findOne(UserQaQuery.findByUserAndQuestionId(userId, id))
            : findOne(UserQaQuery.findByUserAndAnswerId(userId, id));
    ForumUserQaEntity qaEntity;
    boolean opera = true;
    if (!entityOptional.isPresent()) {
      // 初次必然是 true 操作
      qaEntity = new ForumUserQaEntity();
      qaEntity.setUserId(userId);
    } else {
      // 更新操作
      qaEntity = entityOptional.get();
      // 替换 opera 值
      opera = !qaEntity.getToOpera();
    }
    // 更新或新增 qa 关联表
    qaEntity.setToOpera(opera);
    // 更新问题或答案的点赞收藏数量
    if (mode.equals(QUESTION_MODE)) {
      qaEntity.setQuestionId(id);
      questionMapper.updateBy(
          QuestionUpdater.updateCollectUpdater(qaEntity.getQuestionId(), opera));
    } else if (mode.equals(ANSWER_MODE)) {
      qaEntity.setAnswerId(id);
      answerMapper.updateBy(AnswerUpdater.updateGoodUpdater(qaEntity.getAnswerId(), opera));
    }
    try {
      saveOrUpdate(qaEntity);
    } catch (DataIntegrityViolationException e) {
      throw new UserQaException(UserQaStatus.UPDATE_NOT_FOUND);
    }
    return opera;
  }
}
